package org.keyroy.mapEditor.ui.beans;

import java.awt.Point;
import java.awt.Rectangle;
import java.nio.ByteBuffer;
import java.util.Enumeration;
import java.util.List;
import java.util.Random;

import org.keyroy.map.core.Map;
import org.keyroy.map.core.manages.ResourceManage;
import org.keyroy.map.core.overlays.ObjOverlay;
import org.keyroy.map.core.overlays.ObjOverlay.Line;
import org.keyroy.map.core.overlays.TilesOverlay;
import org.keyroy.map.core.sprite.Sprite;
import org.keyroy.util.Base64;

public class MapUtil {

	public static void addLineObject(Map map, String key, int x, int y) {

		// LineObject lineObject = new LineObject();
		// lineObject.name = key;
		// PointObject pointObject = new PointObject();
		// pointObject.point = new Point(x, y);
		// lineObject.lines.add(pointObject);
		// if (map.objOverlay == null) {
		// map.objOverlay = new ObjOverlay();
		// }
		// map.objectOverlay.lines.put(key, lineObject);
	}

	public static void addPointObject(Map map, String key, int x, int y) {
		// PointObject pointObject = new PointObject();
		// pointObject.name = key;
		// pointObject.point = new Point(x, y);
		// if (map.objOverlay == null) {
		// map.objOverlay = new ObjOverlay();
		// }
		// map.objectOverlay.points.put(key, pointObject);
	}

	public static void removePointObject(Map map, ObjOverlay.Point point) {
		if (map.objOverlay != null) {
			// map.objectOverlay.points.remove(point.name);
		}
	}

	public static void setTiles(Map map, Sprite[][] sprites, Point location) {
		if (sprites != null && location != null) {
			setTiles(map.getFloors().tiles, location, sprites);
		}
	}

	public static void setTiles(TilesOverlay overlay, Sprite[][] sprites, Point location) {
		setTiles(overlay.tiles, location, sprites);
	}

	public static void setTiles(Map map, Sprite[][] sprites, Rectangle rectangle, boolean isRandom) {
		if (sprites != null && rectangle != null) {
			fillTiles(map.getFloors().tiles, rectangle, sprites, isRandom);
		}
	}

	public static void setTiles(TilesOverlay overlay, Sprite[][] sprites, Rectangle rectangle, boolean isRandom) {
		fillTiles(overlay.tiles, rectangle, sprites, isRandom);
	}

	private final static void setTiles(Sprite[][] sprites, Point location, Sprite[][] addSprites) {
		for (int x = 0; x < addSprites.length; x++) {
			for (int y = 0; y < addSprites[x].length; y++) {
				int tx = location.x + x;
				int ty = location.y + y;
				if (between(tx, 0, sprites.length - 1) && between(ty, 0, sprites[x].length - 1)) {
					sprites[tx][ty] = addSprites[x][y];
				}
			}
		}
	}

	private final static void fillTiles(Sprite[][] sprites, Rectangle rectangle, Sprite[][] addSprites, boolean isRandom) {
		Random random = new Random();
		for (int i = rectangle.x; i <= rectangle.x + rectangle.width; i++) {
			for (int j = rectangle.y; j <= rectangle.y + rectangle.height; j++) {
				int x = 0, y = 0;
				if (isRandom) {
					x = random.nextInt(addSprites.length);
					y = random.nextInt(addSprites[0].length);
				} else {
					x = (i - rectangle.x) % addSprites.length;
					y = (j - rectangle.y) % addSprites[0].length;
				}

				if (between(i, 0, sprites.length - 1) && between(j, 0, sprites[x].length - 1)) {
					sprites[i][j] = addSprites[x][y];
				}

			}
		}
	}

	private static final boolean between(int b, int a, int c) {
		return b >= a && b <= c;
	}

	public static void cleanTiles(Map map, Rectangle rectangle) {
		if (rectangle != null) {
			for (int x = 0; x <= rectangle.width; x++) {
				for (int y = 0; y <= rectangle.height; y++) {
					int tx = x + rectangle.x;
					int ty = y + rectangle.y;
					if (between(tx, 0, map.getColumns() - 1) && between(ty, 0, map.getRows() - 1)) {
						map.getFloors().tiles[tx][ty] = null;
					}
				}
			}
		}
	}

	public static void cleanTiles(TilesOverlay tilesOverlay, Rectangle rectangle) {
		if (rectangle != null) {
			for (int x = 0; x <= rectangle.width; x++) {
				for (int y = 0; y <= rectangle.height; y++) {
					int tx = x + rectangle.x;
					int ty = y + rectangle.y;

					if (between(tx, 0, tilesOverlay.tiles.length - 1)
							&& between(ty, 0, tilesOverlay.tiles[0].length - 1)) {
						tilesOverlay.tiles[tx][ty] = null;
					}
				}
			}
		}
	}

	public static void cleanPointObj(ObjOverlay objOverlay, Rectangle rectangle) {
		if (rectangle != null) {
			Enumeration<ObjOverlay.ObjGroup> groups = objOverlay.groups.elements();
			while (groups.hasMoreElements()) {
				ObjOverlay.ObjGroup objGroup = (ObjOverlay.ObjGroup) groups.nextElement();

				Enumeration<ObjOverlay.Point> points = objGroup.points.elements();
				while (points.hasMoreElements()) {
					ObjOverlay.Point point = (ObjOverlay.Point) points.nextElement();

					if (between(point.x, rectangle.x, rectangle.x + rectangle.width)
							&& between(point.y, rectangle.y, rectangle.y + rectangle.height)) {
						objGroup.points.remove(point.name);
					}
				}
			}
		}
	}

	public static void cleanLineObj(ObjOverlay objOverlay, Rectangle rectangle) {
		if (rectangle != null) {
			Enumeration<ObjOverlay.ObjGroup> groups = objOverlay.groups.elements();
			while (groups.hasMoreElements()) {
				ObjOverlay.ObjGroup objGroup = (ObjOverlay.ObjGroup) groups.nextElement();

				Enumeration<ObjOverlay.Line> lines = objGroup.lines.elements();
				while (lines.hasMoreElements()) {
					Line line = lines.nextElement();
					List<ObjOverlay.Point> points = line.points;
					for (int i = 0; i < points.size(); i++) {
						ObjOverlay.Point point = points.get(i);
						if (between(point.x, rectangle.x, rectangle.x + rectangle.width)
								&& between(point.y, rectangle.y, rectangle.y + rectangle.height)) {
							line.points.remove(point);
						}
					}

				}
			}
		}
	}

	public static void reset(java.awt.Rectangle rectangle) {
		int x = rectangle.x;
		int y = rectangle.y;
		int width = rectangle.width;
		int height = rectangle.height;

		if (width < 0) {
			x = x + width;
			width = Math.abs(width);

			if (x < 0) {
				x = 0;
			}
		}

		if (height < 0) {
			y = y + height;
			height = Math.abs(height);

			if (y < 0) {
				y = 0;
			}
		}

		rectangle.setBounds(x, y, width, height);
	}

	public static void reset(org.eclipse.swt.graphics.Rectangle rectangle) {
		int x = rectangle.x;
		int y = rectangle.y;
		int width = rectangle.width;
		int height = rectangle.height;

		if (width < 0) {
			x = x + width;
			width = Math.abs(width);
		}

		if (height < 0) {
			y = y + height;
			height = Math.abs(height);
		}

		rectangle.x = x;
		rectangle.y = y;
		rectangle.width = width;
		rectangle.height = height;
	}

	public static final String strings(Enumeration<String> strings) {
		StringBuffer stringBuffer = new StringBuffer();
		while (strings.hasMoreElements()) {
			String string = (String) strings.nextElement();
			stringBuffer.append(string).append(',');
		}

		if (stringBuffer.length() > 0) {
			stringBuffer.deleteCharAt(stringBuffer.length() - 1);
			return stringBuffer.toString();
		}

		return null;
	}

	public static final void strings(List<String> strings, String src) {
		String[] strs = src.split(",");
		for (int i = 0; i < strs.length; i++) {
			strings.add(strs[i]);
		}
	}

	public static final String tiles2String(List<Sprite> sprites) {
		ByteBuffer buffer = ByteBuffer.allocate(sprites.size() * 4);
		for (int i = 0; i < sprites.size(); i++) {
			buffer.putInt(sprites.get(i).ID);
		}

		byte[] data = buffer.array();
		return new String(Base64.encode(data));
	}

	public static final void string2Tiles(List<Sprite> sprites, String tilesString) {
		byte[] data = Base64.decode(tilesString.getBytes());
		ByteBuffer byteBuffer = ByteBuffer.wrap(data);
		for (int i = 0; i < data.length; i += 4) {
			sprites.add(ResourceManage.getSprite(byteBuffer.getInt()));
		}
	}

	public static final String tiles2String(Sprite[][] sprites) {
		try {
			ByteBuffer buffer = ByteBuffer.allocate(sprites.length * sprites[0].length * 4);
			for (int y = 0; y < sprites[0].length; y++) {
				for (int x = 0; x < sprites.length; x++) {
					if (sprites[x][y] != null && sprites[x][y].ID > 0) {
						buffer.putInt(sprites[x][y].ID);
					} else {
						buffer.putInt(0);
					}
				}
			}

			byte[] data = buffer.array();
			return new String(Base64.encode(data));
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	public static final void string2Tiles(Sprite[][] sprites, String tilesString) {
		try {
			byte[] data = Base64.decode(tilesString.getBytes());
			ByteBuffer byteBuffer = ByteBuffer.wrap(data);
			for (int y = 0; y < sprites[0].length; y++) {
				for (int x = 0; x < sprites.length; x++) {
					int ID = byteBuffer.getInt();
					if (ID > 0) {
						sprites[x][y] = ResourceManage.getSprite(ID);
					}
				}
			}

		} catch (Exception e) {
		}
	}
}
